package com.handydata.antifraud.rule.funcs;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * 根据两点之间经纬度计算距离
 */
@Slf4j
public abstract class CalcDistanceByLatAndLng extends CalculateAdapter {
    private static final double EARTH_RADIUS = 6378.137;
    protected static final double LAT_LNG_DEFAULT_VALUE = 999;
    protected static final double DEFAULT_DISTANCE = 0;

    private double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 通过经纬度计算两点之间距离
     * @param lat1 地点1维度
     * @param lng1 地点1经度
     * @param lat2 地点2维度
     * @param lng2 地点2经度
     * @return
     */
    protected double getDistance(double lat1, double lng1, double lat2, double lng2) {
        if(isInValid(lat1, lng1, lat2, lng2)) {
            log.warn("两点之间的经纬度[lat1={},lng1={},lat2={},lng2={}]都相等或有等于默认值:{}",lat1, lng1, lat2, lng2, LAT_LNG_DEFAULT_VALUE);
            return DEFAULT_DISTANCE;
        }
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = Math.abs(radLat1 - radLat2);
        double b = Math.abs(rad(lng1) - rad(lng2));
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
                Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
        s = s * EARTH_RADIUS * 1000;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    private boolean isInValid(double lat1, double lng1, double lat2, double lng2) {
        return (lat1 == lat2 && lng1 == lng2)
                || lat1 == LAT_LNG_DEFAULT_VALUE
                || lng1 == LAT_LNG_DEFAULT_VALUE
                || lat2 == LAT_LNG_DEFAULT_VALUE
                || lng2 == LAT_LNG_DEFAULT_VALUE;
    }

    protected double[] getLatAndLng(String gps) {
        if(StringUtils.isNotEmpty(gps)) {
            try {
                JSONObject json = JSON.parseObject(map(gps));
                return new double[]{Double.valueOf(json.getString("lat")), Double.valueOf(json.getString("lng"))};
            } catch (Exception e) {
                log.warn("经纬度json[{}]解析出错,返回默认值为[{},{}]", gps, LAT_LNG_DEFAULT_VALUE, LAT_LNG_DEFAULT_VALUE);
            }
        } else {
            log.warn("经纬度为空,返回默认值为[{},{}]", LAT_LNG_DEFAULT_VALUE, LAT_LNG_DEFAULT_VALUE);
        }
        return new double[]{0,0};
    }

    protected String map(String str) {
        return str;
    }
}
